/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.rpc.workflow.user;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.spring.SpringContextHolder;
import com.je.common.base.util.JEUUID;
import com.je.common.base.util.SecurityUserHolder;
import com.je.common.base.util.StringUtil;
import com.je.common.base.util.TreeUtil;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.rbac.model.AssignmentPermission;
import com.je.rbac.rpc.CompanyRpcService;
import com.je.rbac.rpc.TreatableUserRpcService;
import com.je.rbac.rpc.workflow.user.special.SpecialUserParserEnum;
import com.je.rbac.rpc.workflow.user.special.SpecialUserParserFactory;
import com.je.rbac.rpc.workflow.util.WorkFlowParserUserUtil;
import com.je.rbac.service.IconType;
import com.je.rbac.service.company.RbacDepartmentService;
import org.apache.commons.lang.StringUtils;
import org.apache.servicecomb.provider.pojo.RpcSchema;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Field;
import java.util.*;

@RpcSchema(schemaId = "treatableUserRpcService")
public class TreatableUserRpcServiceImpl implements TreatableUserRpcService, TreatableUserService {

    @Autowired
    private BeanService beanService;

    @Autowired
    private MetaService metaService;

    @Autowired
    private CompanyRpcService companyRpcService;

    @Autowired
    private RbacDepartmentService rbacDepartmentService;

    @Override
    public JSONTreeNode findRoleUsersAndBuildTreeNode(String accountId, String roleIds, AssignmentPermission perm, Boolean orgFlag, Boolean multiple, Boolean addOwn) {
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        DynaBean table = beanService.getResourceTable("JE_RBAC_ROLE");
        List<DynaBean> columns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
        JSONTreeNode template = beanService.buildJSONTreeNodeTemplate(columns);
        List<String> roleIdList = Splitter.on(",").splitToList(roleIds);
        List<DynaBean> beanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder().in("JE_RBAC_ROLE_ID", roleIdList).apply("ORDER BY SY_TREEORDERINDEX ASC , SY_ORDERINDEX ASC"));
        for (DynaBean eachBean : beanList) {

            eachBean.put("ROLE_ICONCLS", IconType.TCONTYPE_ROLE.getVal());
            JSONTreeNode node = buildTreeNode(template, rootNode.getId(), eachBean);
            if (node != null) {
                rootNode.getChildren().add(node);
            }
        }
        //根据userId,deptId,perm权限过滤
        DynaBean vaccountDeptBean = findVacCountDeptUserById(accountId);

        //根据角色id查询"账号部门角色"表 JE_RBAC_ACCOUNTROLE 取出所有账号数据
        List<DynaBean> accountRoleBeanList = metaService.select("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder().in("ACCOUNTROLE_ROLE_ID", roleIdList));
        Set<String> accountList = new HashSet<>();
        for (DynaBean accountRoleBean : accountRoleBeanList) {
            if (!addOwn) {
                if (accountRoleBean.getStr("ACCOUNTROLE_ACCOUNT_ID").equals(vaccountDeptBean.getStr("JE_RBAC_ACCOUNT_ID"))) {
                    continue;
                }
            }
            accountList.add(accountRoleBean.getStr("ACCOUNTROLE_ACCOUNT_ID"));
        }

        //根据权限过滤用户
        List<DynaBean> accountDeptBeanList = getUserDeptBeanListByUserIds(accountList, vaccountDeptBean, perm);

        //存放accountId，roleIds
        Map<String, List<String>> map = new HashMap<>();
        List<String> roleIdStr = null;
        for (DynaBean accountRoleBean : accountRoleBeanList) {
            String key = accountRoleBean.getStr("ACCOUNTROLE_ACCOUNT_ID") + "," + accountRoleBean.getStr("ACCOUNTROLE_DEPT_ID");
            if (map.containsKey(key)) {
                roleIdStr = map.get(key);
                roleIdStr.add(accountRoleBean.getStr("ACCOUNTROLE_ROLE_ID"));
                map.put(key, roleIdStr);
            } else {
                roleIdStr = new ArrayList<>();
                roleIdStr.add(accountRoleBean.getStr("ACCOUNTROLE_ROLE_ID"));
                map.put(key, roleIdStr);
            }
        }

        //根据已经过滤好的账号部门-角色；对数据进行赋值角色ids
        for (DynaBean eachAccountDeptBean : accountDeptBeanList) {
            String key = eachAccountDeptBean.getStr("JE_RBAC_ACCOUNT_ID") + "," + eachAccountDeptBean.getStr("ACCOUNTDEPT_DEPT_ID");
            if (map.containsKey(key)) {
                eachAccountDeptBean.setStr("ACCOUNTROLE_ROLE_IDS", StringUtils.join(map.get(key), ","));
            }
        }
        rootNode = buildRoleAccountDeptTreeNode(rootNode, accountDeptBeanList, multiple);
        //去掉子级没有数据的节点
        if (null == rootNode.getChildren() && rootNode.getChildren().size() <= 0) {
            return rootNode;
        }
        JSONTreeNode newRootNode = TreeUtil.buildRootNode();
        for (JSONTreeNode node : rootNode.getChildren()) {
            if (node.getChildren().size() > 0) {
                newRootNode.getChildren().add(node);
            }
        }
        rootNode = newRootNode;
        //是否按照公司展示
        //人员不属于同一个公司、如果多个公司并且按照公司展示为true 按公司展示
        //如果都属于一个公司、不按公司展示
        HashSet<String> companyIdSet = new HashSet<>();
        for (DynaBean dynaBean : accountDeptBeanList) {
            if (dynaBean.getStr("SY_COMPANY_ID") != null) {
                companyIdSet.add(dynaBean.getStr("SY_COMPANY_ID"));
            }
        }

        if (orgFlag && companyIdSet.size() > 1) {
            rootNode = buildCompanyTreeNode(rootNode, accountDeptBeanList);
        }

        for (JSONTreeNode node : rootNode.getChildren()) {
            node.setExpanded(true);
        }
        return rootNode;
    }

    @Override
    public Boolean checkRoleContainsCurrentUser(String accountId, String roleIds, AssignmentPermission perm) {
        List<String> roleIdList = Splitter.on(",").splitToList(roleIds);
        //根据userId,deptId,perm权限过滤
        DynaBean vaccountDeptBean = findVacCountDeptUserById(accountId);
        //根据角色id查询"账号部门角色"表 JE_RBAC_ACCOUNTROLE 取出所有账号数据
        List<DynaBean> accountRoleBeanList = metaService.select("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder().in("ACCOUNTROLE_ROLE_ID", roleIdList));
        Set<String> accountList = new HashSet<>();
        for (DynaBean accountRoleBean : accountRoleBeanList) {
            accountList.add(accountRoleBean.getStr("ACCOUNTROLE_ACCOUNT_ID"));
        }
        //根据权限过滤用户
        List<DynaBean> accountDeptBeanList = getUserDeptBeanListByUserIds(accountList, vaccountDeptBean, perm);

        for (DynaBean dynaBean : accountDeptBeanList) {
            if (accountId.equals(dynaBean.getStr("JE_RBAC_ACCOUNTDEPT_ID"))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 查询唯一信息，账号部门视图 JE_RBAC_VACCOUNTDEPT
     *
     * @param countUserId
     * @return
     */
    public DynaBean findVacCountDeptUserById(String countUserId) {
        MetaService metaService = SpringContextHolder.getBean(MetaService.class);
        DynaBean countDept = metaService.selectOne("JE_RBAC_VACCOUNTDEPT",
                ConditionsWrapper.builder().eq("JE_RBAC_ACCOUNTDEPT_ID", countUserId).eq("SY_STATUS", "1"));
        return countDept;
    }

    /***
     * 根据用户ids获取 JE_RBAC_VACCOUNTDEPT 账号部门信息
     * @param accountList
     * @param vaccountDeptBean
     * @param perm
     * @return
     */
    public List<DynaBean> getUserDeptBeanListByUserIds(Set<String> accountList, DynaBean vaccountDeptBean, AssignmentPermission perm) {
        ConditionsWrapper conditionsWrapper = ConditionsWrapper.builder().in("JE_RBAC_ACCOUNT_ID", accountList).eq("SY_STATUS", "1");
        if (!Strings.isNullOrEmpty(perm.getSql())) {
            conditionsWrapper.apply(perm.getSql());
        }
        conditionsWrapper.orderByAsc("SY_ORDERINDEX");
        //根据accountList查询账号部门信息
        List<DynaBean> accountDeptBeanList = metaService.select("JE_RBAC_VACCOUNTDEPT", conditionsWrapper);
        //根据权限过滤用户
        if (null != vaccountDeptBean) {
            accountDeptBeanList = getUserListByPerm(vaccountDeptBean, perm, accountDeptBeanList);
        }
        return accountDeptBeanList;
    }

    /***
     * 人员权限过滤
     * @param vaccountBean
     * @param perm
     * @param accountDeptBeanList
     * @return
     */
    public List<DynaBean> getUserListByPerm(DynaBean vaccountBean, AssignmentPermission perm, List<DynaBean> accountDeptBeanList) {
        if (checkObjAllFieldsIsNull(perm)) {
            return accountDeptBeanList;
        }
        if (!perm.getCompany() && !perm.getCompanySupervision() && !perm.getDept() && !perm.getDeptAll()
                && !perm.getDirectLeader() && !perm.getDeptLeader() && !perm.getSupervisionLeader()) {
            return accountDeptBeanList;
        }
        //存放所有匹配过滤条件的账号部门数据
        List<DynaBean> matchList = new ArrayList<>();
        for (DynaBean bean : accountDeptBeanList) {
            //公司内可见
            if (null != perm.getCompany() && perm.getCompany() && bean != null && bean.get("SY_COMPANY_ID") != null && bean.get("SY_COMPANY_ID").equals(vaccountBean.get("SY_COMPANY_ID"))) {
                matchList.add(bean);
            }

            //公司监管可见
            if (null != perm.getCompanySupervision() && perm.getCompanySupervision()) {
                DynaBean beanCompanyBean = metaService.selectOne("JE_RBAC_COMPANY", ConditionsWrapper.builder().eq("JE_RBAC_COMPANY_ID", bean.get("SY_COMPANY_ID")));
                if (beanCompanyBean != null && beanCompanyBean.getStr("COMPANY_JGCOMPANY_ID").contains(vaccountBean.getStr("SY_COMPANY_ID"))) {
                    matchList.add(bean);
                }
            }
            //本部门
            if (null != perm.getDept() && perm.getDept() && null != vaccountBean.get("ACCOUNTDEPT_DEPT_ID") && vaccountBean.get("ACCOUNTDEPT_DEPT_ID").equals(bean.get("ACCOUNTDEPT_DEPT_ID"))) {
                matchList.add(bean);
            }
            //部门内包含子部门
            if (null != perm.getDeptAll() && perm.getDeptAll() && null != vaccountBean.get("ACCOUNTDEPT_DEPT_ID")) {
                List<String> deptIdsList = rbacDepartmentService.findAllPathDepartments(vaccountBean.getStr("ACCOUNTDEPT_DEPT_ID"));
                if (null != deptIdsList && deptIdsList.size() > 0) {
                    if (deptIdsList.contains(bean.getStr("ACCOUNTDEPT_DEPT_ID"))) {
                        matchList.add(bean);
                    }
                }
            }

            //根据vaccountBeanBean 人员id，JE_RBAC_VDEPTUSER 找到直属领导userid
            DynaBean accountDept = metaService.selectOne("JE_RBAC_VDEPTUSER",
                    ConditionsWrapper.builder().eq("JE_RBAC_USER_ID", vaccountBean.getStr("USER_ASSOCIATION_ID"))
                            .eq("JE_RBAC_DEPARTMENT_ID", vaccountBean.getStr("ACCOUNTDEPT_DEPT_ID")));

            //直属领导可见 DEPTUSER_DIRECTLEADER_ID
            if (null != perm.getDirectLeader() && perm.getDirectLeader() && null != accountDept && null != accountDept.get("DEPTUSER_DIRECTLEADER_ID") && bean.get("USER_ASSOCIATION_ID").equals(accountDept.get("DEPTUSER_DIRECTLEADER_ID"))) {
                matchList.add(bean);
            }
            //部门领导 deptLeader  多个
            if (null != perm.getDeptLeader() && perm.getDeptLeader()) {
                //查找部门领导所属部门列表，若人员中有匹配其中部门，则添加
                if (accountDept.getStr("DEPARTMENT_MAJOR_ID").contains(bean.getStr("USER_ASSOCIATION_ID"))) {
                    matchList.add(bean);
                }
            }
            //监管领导 supervisionLeader  多个
            if (null != perm.getSupervisionLeader() && perm.getSupervisionLeader()) {
                //人员所在部门
                DynaBean eachBeanDept = metaService.selectOne("JE_RBAC_DEPARTMENT",
                        ConditionsWrapper.builder().eq("JE_RBAC_DEPARTMENT_ID", bean.getStr("ACCOUNTDEPT_DEPT_ID")));
                //人员部门关系
                DynaBean accountUserDept = metaService.selectOne("JE_RBAC_VDEPTUSER",
                        ConditionsWrapper.builder().eq("JE_RBAC_USER_ID", bean.getStr("USER_ASSOCIATION_ID"))
                                .eq("JE_RBAC_DEPARTMENT_ID", bean.getStr("ACCOUNTDEPT_DEPT_ID")));

                if (eachBeanDept != null && !Strings.isNullOrEmpty(eachBeanDept.getStr("DEPARTMENT_MONITORDEPT_ID"))) {
                    //若人员该部门监管了 当前人的部门
                    if (eachBeanDept.getStr("DEPARTMENT_MONITORDEPT_ID").contains(vaccountBean.getStr("ACCOUNTDEPT_DEPT_ID"))) {
                        matchList.add(bean);
                    }
                }
                //人员监管部门为 当前人的部门
                if (accountUserDept != null && !Strings.isNullOrEmpty(accountUserDept.getStr("USER_MONITORDEPT_ID")) && accountUserDept.getStr("USER_MONITORDEPT_ID").contains(vaccountBean.getStr("ACCOUNTDEPT_DEPT_ID"))) {
                    matchList.add(bean);
                }
            }
        }
        accountDeptBeanList = new ArrayList<DynaBean>(new LinkedHashSet<>(matchList));
        return accountDeptBeanList;
    }

    /**
     * 判断对象属性是否全部为空，是返回true
     *
     * @param object
     * @return
     */
    private static boolean checkObjAllFieldsIsNull(Object object) {
        if (null == object) {
            return true;
        }
        try {
            for (Field f : object.getClass().getDeclaredFields()) {
                f.setAccessible(true);
                if (f.get(object) != null && StringUtils.isNotBlank(f.get(object).toString())) {
                    return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }


    /***
     * 构建角色账号树
     * @param rootNode
     * @param accountDeptBeanList
     * @return
     */
    public JSONTreeNode buildRoleAccountDeptTreeNode(JSONTreeNode rootNode, List<DynaBean> accountDeptBeanList, Boolean multiple) {
        //加入账号node数据
        if (null == rootNode.getChildren() && rootNode.getChildren().size() <= 0) {
            return rootNode;
        }
        for (int i = 0; i < rootNode.getChildren().size(); i++) {
            JSONTreeNode eachNode = rootNode.getChildren().get(i);
            if (null == accountDeptBeanList) {
                break;
            }
            for (DynaBean accountDeptBean : accountDeptBeanList) {
                if (Strings.isNullOrEmpty(accountDeptBean.getStr("ACCOUNTROLE_ROLE_IDS"))) {
                    continue;
                }
                if (!accountDeptBean.getStr("ACCOUNTROLE_ROLE_IDS").contains(eachNode.getBean().get("JE_RBAC_ROLE_ID") + "")) {
                    continue;
                }
                //判断当前角色下
                WorkFlowParserUserUtil.parseAccountDepartmentToTree(eachNode, accountDeptBean, multiple, true);
            }
        }
        return rootNode;
    }

    /***
     * 根据角色关联人员-构建公司Node
     * @param rootNode
     * @param accountDeptBeanList
     * @return
     */
    public JSONTreeNode buildCompanyTreeNode(JSONTreeNode rootNode, List<DynaBean> accountDeptBeanList) {
        //遍历角色层级
        for (JSONTreeNode roleNode : rootNode.getChildren()) {

            //遍历角色下人员层级,取出该角色下所有人所属公司id
            Set<String> obj = new HashSet<>();
            //没有所属公司的，是外部机构人员
            Set<JSONTreeNode> orgUserNodeJsons = new HashSet<>();
            for (JSONTreeNode userNode : roleNode.getChildren()) {
                if (null != userNode.getBean().get("SY_COMPANY_ID")) {
                    if (userNode.getBean().get("SY_COMPANY_ID") instanceof String &&
                            !Strings.isNullOrEmpty((String) userNode.getBean().get("SY_COMPANY_ID"))) {
                        obj.add(String.valueOf(userNode.getBean().get("SY_COMPANY_ID")));
                    }
                } else {
                    orgUserNodeJsons.add(userNode);
                }
            }
            JSONTreeNode companyRootNode = companyRpcService.buildCompanyTree(String.join(",", obj));
            if (null != obj && obj.size() > 0) {
                List<JSONTreeNode> companyListNode = new ArrayList<>();
                for (String companyIdStr : obj) {
                    for (JSONTreeNode companyNode : companyRootNode.getChildren()) {
                        if (companyIdStr.equals(companyNode.getBean().get("JE_RBAC_COMPANY_ID"))) {
                            companyNode.setId(companyNode.getId() + ":" + JEUUID.uuid());
                            companyNode.setParent(roleNode.getId());
                            if (companyNode != null) {
                                companyListNode.add(companyNode);
                            }
                            break;
                        }
                    }
                }
                //对应公司设置人员
                if (null != companyListNode) {
                    for (JSONTreeNode companyNode : companyListNode) {
                        companyNode.setChildren(new ArrayList<>());
                        for (JSONTreeNode userNode : roleNode.getChildren()) {
                            if (companyNode.getBean().get("JE_RBAC_COMPANY_ID").equals(userNode.getBean().get("SY_COMPANY_ID"))) {
                                userNode.setParent(companyNode.getId());
                                companyNode.getChildren().add(userNode);
                            }
                        }
                    }
                }
                JSONTreeNode orgJsonTreeNode = null;
                //公司层级添加同级机构
                if (orgUserNodeJsons.size() > 0) {
                    orgJsonTreeNode = buildOrgTree((new ArrayList<JSONTreeNode>(orgUserNodeJsons)), roleNode);
                    if (orgJsonTreeNode != null) {
                        companyListNode.add(orgJsonTreeNode);
                    }
                }
                //角色设置公司层级
                roleNode.setChildren(companyListNode);
            }
        }
        return rootNode;
    }

    private JSONTreeNode buildOrgTree(List<JSONTreeNode> orgUserNodeJsons, JSONTreeNode roleNode) {
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        String id = JEUUID.uuid();
        rootNode.setId(id);
        rootNode.setParent(roleNode.getId());
        rootNode.setText("外部机构");
        rootNode.setIcon("fas fa-university");
        rootNode.setNodeType("GENERAL");
        for (JSONTreeNode orgUserNodeJson : orgUserNodeJsons) {
            orgUserNodeJson.setParent(id);
        }
        rootNode.setChildren(orgUserNodeJsons);
        return rootNode;
    }


    @Override
    public JSONTreeNode findDeptUsersAndBuildTreeNode(String accountId, String deptIds, AssignmentPermission perm, Boolean orgFlag, Boolean multiple, Boolean addOwn) {
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        DynaBean table = beanService.getResourceTable("JE_RBAC_DEPARTMENT");
        List<DynaBean> columns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
        JSONTreeNode template = beanService.buildJSONTreeNodeTemplate(columns);
        if (Strings.isNullOrEmpty(deptIds)) {
            return null;
        }
        List<String> deptIdList = Splitter.on(",").splitToList(deptIds);

        //根据JE_RBAC_VACCOUNTDEPT 主键JE_RBAC_ACCOUNTDEPT_ID找到账号
        DynaBean accountDeptBean = findVacCountDeptUserById(accountId);
        if (accountDeptBean == null) {
            return null;
        }
        DynaBean orgBean = metaService.selectOne("JE_RBAC_ORG", ConditionsWrapper.builder().eq("JE_RBAC_ORG_ID", accountDeptBean.getStr("SY_ORG_ID")));
        if (orgBean == null || !orgBean.getStr("JE_RBAC_ORG_ID").equals("systemdepartment")) {
            return null;
        }
        //获取级联父级子级部门
        Set<String> allDeptIdList = findAllDeptId(deptIdList);
        List<DynaBean> allDeptBeanList = metaService.select("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder().in("JE_RBAC_DEPARTMENT_ID", allDeptIdList).apply("ORDER BY SY_TREEORDERINDEX ASC , SY_ORDERINDEX ASC"));

        //查询部门下所有账号
        List<String> myDeptIdList = rbacDepartmentService.findAllPathDepartments(StringUtils.join(deptIdList, ","));
        //是否展示自己信息
        List<DynaBean> accountDeptBeanList = null;
        ConditionsWrapper conditionsWrapper = ConditionsWrapper.builder().in("ACCOUNTDEPT_DEPT_ID", myDeptIdList).eq("SY_STATUS", "1");
        if (!Strings.isNullOrEmpty(perm.getSql())) {
            conditionsWrapper.apply(perm.getSql());
        }
        if (!addOwn) {
            accountDeptBeanList = metaService.select("JE_RBAC_VACCOUNTDEPT", conditionsWrapper.ne("JE_RBAC_ACCOUNTDEPT_ID", accountId).orderByAsc("SY_ORDERINDEX"));
        } else {
            accountDeptBeanList = metaService.select("JE_RBAC_VACCOUNTDEPT", conditionsWrapper.orderByAsc("SY_ORDERINDEX"));
        }
        //根据权限过滤用户
        if (null != accountDeptBean) {
            accountDeptBeanList = getUserListByPerm(accountDeptBean, perm, accountDeptBeanList);
        }
        //构建部门树形结构-并加入账号node数据
        recursiveDeptJsonTreeNode(template, rootNode, allDeptBeanList, accountDeptBeanList, multiple);

        //是否按照公司展示
        if (orgFlag) {
            //加入公司层级
            Set<String> companyIds = new HashSet<>();
            for (DynaBean eachAccountDeptBean : accountDeptBeanList) {
                companyIds.add(eachAccountDeptBean.getStr("SY_COMPANY_ID"));
            }
            JSONTreeNode companyRootNode = companyRpcService.buildCompanyTree(String.join(",", companyIds));
            for (int i = 0; i < companyRootNode.getChildren().size(); i++) {
                List<JSONTreeNode> userNodeList = new ArrayList<>();
                for (JSONTreeNode userDeptNode : rootNode.getChildren()) {
                    if (companyRootNode.getChildren().get(i).getBean().get("JE_RBAC_COMPANY_ID").equals(userDeptNode.getBean().get("SY_COMPANY_ID"))) {
                        userDeptNode.setParent(userDeptNode.getBean().get("SY_COMPANY_ID") + "");
                        userNodeList.add(userDeptNode);
                    }
                }
                companyRootNode.getChildren().get(i).setChildren(userNodeList);
            }
            rootNode = companyRootNode;
        }
        for (JSONTreeNode node : rootNode.getChildren()) {
            node.setExpanded(true);
        }
        return rootNode;
    }

    @Override
    public Boolean checkDeptUsersContainsCurrentUser(String accountId, String deptIds, AssignmentPermission perm) {
        if (Strings.isNullOrEmpty(deptIds)) {
            return false;
        }
        List<String> deptIdList = Splitter.on(",").splitToList(deptIds);

        //根据JE_RBAC_VACCOUNTDEPT 主键JE_RBAC_ACCOUNTDEPT_ID找到账号
        DynaBean accountDeptBean = findVacCountDeptUserById(accountId);
        if (accountDeptBean == null) {
            return false;
        }
        DynaBean orgBean = metaService.selectOne("JE_RBAC_ORG", ConditionsWrapper.builder().eq("JE_RBAC_ORG_ID", accountDeptBean.getStr("SY_ORG_ID")));
        if (orgBean == null || !orgBean.getStr("JE_RBAC_ORG_ID").equals("systemdepartment")) {
            return false;
        }
        //查询部门下所有账号
        List<String> myDeptIdList = rbacDepartmentService.findAllPathDepartments(StringUtils.join(deptIdList, ","));
        ConditionsWrapper conditionsWrapper = ConditionsWrapper.builder().in("ACCOUNTDEPT_DEPT_ID", myDeptIdList).eq("SY_STATUS", "1");
        if (!Strings.isNullOrEmpty(perm.getSql())) {
            conditionsWrapper.apply(perm.getSql());
        }
        List<DynaBean> accountDeptBeanList = metaService.select("JE_RBAC_VACCOUNTDEPT", conditionsWrapper);

        //根据权限过滤用户
        if (null != accountDeptBean) {
            accountDeptBeanList = getUserListByPerm(accountDeptBean, perm, accountDeptBeanList);
        }
        for (DynaBean dynaBean : accountDeptBeanList) {
            if (accountId.equals(dynaBean.getStr("JE_RBAC_ACCOUNTDEPT_ID"))) {
                return true;
            }
        }
        return false;
    }

    /***
     * 获取级联父级子级部门
     * @param deptIdList
     * @return
     */
    private Set<String> findAllDeptId(List<String> deptIdList) {
        Set<String> parentDeptList = new HashSet<>();
        List<DynaBean> deptBeanList = metaService.select("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder().eq("SY_STATUS", "1").in("SY_PARENT", "ROOT"));
        for (String deptId : deptIdList) {
            DynaBean deptBean = metaService.selectOne("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder().in("JE_RBAC_DEPARTMENT_ID", deptId).eq("SY_STATUS", "1"));
            if (deptBean != null) {
                for (DynaBean eachOneLevelDeptBean : deptBeanList) {
                    if (deptBean.getStr("JE_RBAC_DEPARTMENT_ID").equals(eachOneLevelDeptBean.getStr("JE_RBAC_DEPARTMENT_ID"))) {
                        //当前部门为顶级
                        String ancestorsDeptId = deptBean.getStr("JE_RBAC_DEPARTMENT_ID");
                        parentDeptList.addAll(rbacDepartmentService.findAllPathDepartments(ancestorsDeptId));
                        break;
                    } else {
                        //非顶级部门
                        if (deptBean.getStr("SY_PATH").contains(eachOneLevelDeptBean.getStr("JE_RBAC_DEPARTMENT_ID"))) {
                            parentDeptList.add(eachOneLevelDeptBean.getStr("JE_RBAC_DEPARTMENT_ID"));
                            parentDeptList.addAll(rbacDepartmentService.findAllPathDepartments(deptBean.getStr("JE_RBAC_DEPARTMENT_ID")));
                        }
                    }
                }
            }

        }
        return parentDeptList;
    }

    /***
     * 构建部门树结构
     * @param template  数据模板
     * @param rootNote  树形根节点
     * @param list      部门数据
     * @param countDepts    部门人员数据
     * @param multiple
     */
    @Override
    public void recursiveSpecialDeptJsonTreeNode(JSONTreeNode template, JSONTreeNode rootNote, List<DynaBean> list, List<DynaBean> countDepts, Boolean multiple) {
        if (list == null || list.isEmpty()) {
            return;
        }
        //构建当前部门账号
        if (countDepts != null && countDepts.size() > 0) {
            for (DynaBean eachAccoutDeptBean : countDepts) {
                if (rootNote.getBean().get("JE_RBAC_DEPARTMENT_ID").equals(eachAccoutDeptBean.getStr("ACCOUNTDEPT_DEPT_ID"))) {
//                    rootNote.setId(rootNote.getId() + ":" + JEUUID.uuid());
                    WorkFlowParserUserUtil.parseAccountDepartmentToTree(rootNote, eachAccoutDeptBean, multiple, false);
                }
            }
        }

        //构建子级部门账号
        for (DynaBean eachBean : list) {
            if (rootNote.getId().equals(eachBean.getStr("SY_PARENT"))) {
                JSONTreeNode departmentNode = buildDeptTreeNode(template, rootNote.getId(), eachBean);
                //构建树形结构-加入账号node数据
                recursiveDeptAccountTreeNode(departmentNode, countDepts, multiple);
                recursiveDepartmentJsonTreeNode(template, departmentNode, list, countDepts, multiple);
                if (departmentNode.getChildren().size() > 0) {
                    rootNote.getChildren().add(departmentNode);
                }

            }
        }
    }


    /***
     * 构建部门树结构
     * @param template  数据模板
     * @param rootNote  树形根节点
     * @param list      部门数据
     * @param countDepts    部门人员数据
     * @param multiple
     */
    @Override
    public void recursiveDeptJsonTreeNode(JSONTreeNode template, JSONTreeNode rootNote, List<DynaBean> list, List<DynaBean> countDepts, Boolean multiple) {
        if (list == null || list.isEmpty()) {
            return;
        }
        for (DynaBean eachBean : list) {
            if ("ROOT".equals(eachBean.getStr("SY_PARENT"))) {
                JSONTreeNode departmentNode = buildDeptTreeNode(template, rootNote.getId(), eachBean);
                //构建树形结构-加入账号node数据
                recursiveDeptAccountTreeNode(departmentNode, countDepts, multiple);
                recursiveDepartmentJsonTreeNode(template, departmentNode, list, countDepts, multiple);
                if (departmentNode.getChildren().size() > 0) {
                    rootNote.getChildren().add(departmentNode);
                }

            }
        }
    }

    /***
     * 递归构建部门树节点
     * @param template
     * @param rootNode
     * @param list
     * @param countDepts
     * @param multiple
     */
    public void recursiveDepartmentJsonTreeNode(JSONTreeNode template, JSONTreeNode rootNode, List<DynaBean> list, List<DynaBean> countDepts, Boolean multiple) {
        if (list == null || list.isEmpty()) {
            return;
        }
        JSONTreeNode treeNode;
        for (DynaBean eachBean : list) {
            if (null != rootNode.getBean().get("JE_RBAC_DEPARTMENT_ID")
                    && rootNode.getBean().get("JE_RBAC_DEPARTMENT_ID").equals(eachBean.getStr("SY_PARENT"))
                    && "department".equals(rootNode.getNodeInfoType())) {
                treeNode = buildDeptTreeNode(template, rootNode.getId(), eachBean);
                //构建树形结构-加入账号node数据
                recursiveDeptAccountTreeNode(treeNode, countDepts, multiple);
                if (treeNode.getChildren().size() > 0) {
                    rootNode.getChildren().add(treeNode);
                }
            }
        }

        if (rootNode.getChildren() == null || rootNode.getChildren().isEmpty()) {
            rootNode.setLeaf(true);
            return;
        }
        rootNode.setLeaf(false);

        for (JSONTreeNode eachNode : rootNode.getChildren()) {
            recursiveDepartmentJsonTreeNode(template, eachNode, list, countDepts, multiple);
        }
    }

    /**
     * 构建树形节点
     *
     * @param template     模板
     * @param parentNodeId 父节点ID
     * @param bean         当前bean
     * @return
     */
    @Override
    public JSONTreeNode buildDeptTreeNode(JSONTreeNode template, String parentNodeId, DynaBean bean) {
        JSONTreeNode node = new JSONTreeNode();
        node.setId(bean.getPkValue());
        node.setParent(parentNodeId);
        node.setLeaf(true);
        if (StringUtil.isNotEmpty(template.getText())) {
            node.setText(bean.getStr(template.getText()));
        }
        if (StringUtil.isNotEmpty(template.getCode())) {
            node.setCode(bean.getStr(template.getCode()));
        }
        //节点信息
        node.setNodeInfo(bean.getStr(template.getCode()));
        //节点信息类型
        node.setNodeInfoType("department");
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(bean.getStr(template.getNodeType()));
        }
        //节点路径
        if (StringUtil.isNotEmpty(template.getNodePath())) {
            node.setNodePath(bean.getStr(template.getNodePath()));
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(bean.getStr(template.getDisabled()));
        }
        //树形排序
        if (StringUtil.isNotEmpty(template.getTreeOrderIndex())) {
            node.setTreeOrderIndex(bean.getStr(template.getTreeOrderIndex()));
        }
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(bean.getStr(template.getNodeType()));
        }
        //图标样式
        if (StringUtil.isNotEmpty(template.getIcon())) {
            node.setIcon(bean.getStr(template.getIcon()));
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(bean.getStr(template.getDisabled()));
        } else {
            node.setDisabled("0");
        }
        //描述
        if (StringUtil.isNotEmpty(template.getDescription())) {
            node.setDescription(bean.getStr(template.getDescription()));
        }
        //排序
        if (StringUtil.isNotEmpty(template.getOrderIndex())) {
            node.setOrderIndex(bean.getStr(template.getOrderIndex()) + "");
        }
        node.setBean(bean.getValues());
        return node;
    }


    @Override
    public JSONTreeNode findUsersAndBuildTreeNodeByAccountIds(List<String> accountIds, Boolean orgFlag, Boolean multiple, Boolean addOwn) {
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        //是否展示自己信息
        if (!addOwn) {
            accountIds.remove(SecurityUserHolder.getCurrentAccount().getDeptId());
        }
        List<DynaBean> countDepts = metaService.select("JE_RBAC_VACCOUNTDEPT",
                ConditionsWrapper.builder().in("JE_RBAC_ACCOUNTDEPT_ID", accountIds).eq("SY_STATUS", "1")
                        .orderByAsc("SY_ORDERINDEX"));
        for (DynaBean account : countDepts) {
            WorkFlowParserUserUtil.parseAccountDepartmentToTree(rootNode, account, multiple, true);
        }
        //是否按照公司展示
        if (orgFlag) {
            //加入公司层级
            Set<String> companyIds = new HashSet<>();
            for (DynaBean eachDepartmentUserBean : countDepts) {
                companyIds.add(eachDepartmentUserBean.getStr("SY_COMPANY_ID"));
            }
            JSONTreeNode companyRootNode = companyRpcService.buildCompanyTree(String.join(",", companyIds));
            for (JSONTreeNode companyNode : companyRootNode.getChildren()) {
                List<JSONTreeNode> userNodeList = new ArrayList<>();
                for (JSONTreeNode userDeptNode : rootNode.getChildren()) {
                    if (companyNode.getBean().get("JE_RBAC_COMPANY_ID").equals(userDeptNode.getBean().get("SY_COMPANY_ID"))) {
                        userDeptNode.setParent(companyNode.getBean().get("JE_RBAC_COMPANY_ID").toString());
                        userNodeList.add(userDeptNode);
                    }
                }
                companyNode.setChildren(userNodeList);
            }
            rootNode = companyRootNode;
        }
        for (JSONTreeNode node : rootNode.getChildren()) {
            node.setExpanded(true);
        }
        return rootNode;
    }


    @Override
    public JSONTreeNode findOrgStructureAndBuildTreeNode(String accountId, AssignmentPermission perm, Boolean multiple, Boolean addOwn) {
        JSONTreeNode companyNode = rbacDepartmentService.buildOneCompanyTreeData();
        //是否展示自己信息
        List<DynaBean> countDepts = null;
        if (!addOwn) {
            countDepts = metaService.select("JE_RBAC_VACCOUNTDEPT", ConditionsWrapper.builder().eq("SY_STATUS", "1")
                    .ne("JE_RBAC_ACCOUNTDEPT_ID", accountId).orderByAsc("SY_ORDERINDEX"));
        } else {
            countDepts = metaService.select("JE_RBAC_VACCOUNTDEPT", ConditionsWrapper.builder().eq("SY_STATUS", "1").orderByAsc("SY_ORDERINDEX"));
        }

        //根据userId,deptId,perm权限过滤
        DynaBean userDeptBean = findVacCountDeptUserById(accountId);
        //根据权限过滤用户
        if (null != userDeptBean) {
            countDepts = getUserListByPerm(userDeptBean, perm, countDepts);
        }
        recursiveDeptAccountTreeNode(companyNode, countDepts, multiple);
        for (JSONTreeNode node : companyNode.getChildren()) {
            node.setExpanded(true);
        }
        return companyNode;
    }

    /***
     * 构建部门账号
     * @param rootNode  部门节点
     * @param countDepts    部门人员
     */
    public void recursiveDeptAccountTreeNode(JSONTreeNode rootNode, List<DynaBean> countDepts, Boolean multiple) {
        if ("department".equals(rootNode.getNodeInfoType())) {
            for (DynaBean countDeptBean : countDepts) {
                if (rootNode.getBean().get("JE_RBAC_DEPARTMENT_ID") == null || !rootNode.getBean().get("JE_RBAC_DEPARTMENT_ID").equals(countDeptBean.getStr("ACCOUNTDEPT_DEPT_ID"))) {
                    continue;
                }
                rootNode.setId(rootNode.getId() + ":" + JEUUID.uuid());
                WorkFlowParserUserUtil.parseAccountDepartmentToTree(rootNode, countDeptBean, multiple, false);
            }
        }
        if (rootNode.getChildren() == null || rootNode.getChildren().isEmpty()) {
            return;
        }
        for (JSONTreeNode eachChildNode : rootNode.getChildren()) {
            recursiveDeptAccountTreeNode(eachChildNode, countDepts, multiple);
        }
    }

    /**
     * 构建树形节点
     *
     * @param template     模板
     * @param parentNodeId 父节点ID
     * @param bean         当前bean
     * @return
     */
    private JSONTreeNode buildTreeNode(JSONTreeNode template, String parentNodeId, DynaBean bean) {
        JSONTreeNode node = new JSONTreeNode();
        node.setId(bean.getPkValue());
        node.setParent(parentNodeId);
        node.setLeaf(true);
        if (StringUtil.isNotEmpty(template.getText())) {
            node.setText(bean.getStr(template.getText()));
        }
        if (StringUtil.isNotEmpty(template.getCode())) {
            node.setCode(bean.getStr(template.getCode()));
        }
        //节点信息
        if (StringUtil.isNotEmpty(template.getNodeInfo())) {
            node.setNodeInfo(bean.getStr(template.getNodeInfo()));
        }
        //节点信息类型
        if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
            node.setNodeInfoType(bean.getStr(template.getNodeInfoType()));
        }
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(bean.getStr(template.getNodeType()));
        }
        //节点路径
        if (StringUtil.isNotEmpty(template.getNodePath())) {
            node.setNodePath(bean.getStr(template.getNodePath()));
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(bean.getStr(template.getDisabled()));
        }
        //树形排序
        if (StringUtil.isNotEmpty(template.getTreeOrderIndex())) {
            node.setTreeOrderIndex(bean.getStr(template.getTreeOrderIndex()));
        }
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(bean.getStr(template.getNodeType()));
        }
        //图标样式
        if (StringUtil.isNotEmpty(template.getIcon())) {
            node.setIcon(bean.getStr(template.getIcon()));
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(bean.getStr(template.getDisabled()));
        } else {
            node.setDisabled("0");
        }
        //描述
        if (StringUtil.isNotEmpty(template.getDescription())) {
            node.setDescription(bean.getStr(template.getDescription()));
        }
        //排序
        if (StringUtil.isNotEmpty(template.getOrderIndex())) {
            node.setOrderIndex(bean.getStr(template.getOrderIndex()) + "");
        }
        node.setBean(bean.getValues());
        return node;
    }

    @Override
    public JSONTreeNode findUserToSpecialProcessing(List<String> types, String userId, String taskAssigner, String frontTaskAssigner,
                                                    String starterUser, Boolean multiple, Boolean addOwn) {
        //构建根节点
        JSONTreeNode resultJSONTreeNode = TreeUtil.buildRootNode();
        JsonTreeContext jsonTreeContext = new JsonTreeContext();
        JsonTreeContext.putJsonTree("ROOT", resultJSONTreeNode);
        ParserUserBo parserUserBo = new ParserUserBo().setTypes(types).setUserId(userId).setTaskAssigner(taskAssigner)
                .setFrontTaskAssigner(frontTaskAssigner).setStarterUser(starterUser).setMultiple(multiple).setAddOwn(addOwn);
        //构建公司、部门、人员树
        ParserCompanyJsonTreeFilter parserCompanyJsonTreeFilter = new ParserCompanyJsonTreeFilter();
        //构建公司人员树
        ParserCompanyUserJsonTreeFilter parserCompanyUserJsonTreeFilter = new ParserCompanyUserJsonTreeFilter();
        //构建部门、人员树
        ParserDepartmentJsonTreeFilter parserDepartmentJsonTreeFilter = new ParserDepartmentJsonTreeFilter();
        //构建用户树
        ParserUserJsonTreeFilter parserUserJsonTreeFilter = new ParserUserJsonTreeFilter();
        //按顺序 公司---部门---用户
        FilterChain filterChain = new FilterChain();
        filterChain.add(parserCompanyJsonTreeFilter).add(parserCompanyUserJsonTreeFilter).add(parserDepartmentJsonTreeFilter)
                .add(parserUserJsonTreeFilter);

        filterChain.doFilter(parserUserBo, resultJSONTreeNode, filterChain);
        JsonTreeContext.clearJsonTree();
        return resultJSONTreeNode;

    }

    @Override
    public Boolean checkSpecialProcessingContainsCurrentUser(List<String> types, String userId, String taskAssigner, String frontTaskAssigner, String starterUser) {
        //账号
        DynaBean userDeptBean = findVacCountDeptUserById(userId);
        for (String type : types) {
            //如果是任务指派人 并且与人员参照人员相等
            if (type.equals(SpecialUserParserEnum.TASK_ASSGINE.toString())) {
                if (type.equals(SpecialUserParserEnum.TASK_ASSGINE.toString()) && taskAssigner.equals(userId)) {
                    return true;
                }
            }
            //如果是任务指派人 直属领导
            if (type.equals(SpecialUserParserEnum.TASK_ASSGINE_HEAD.toString())) {
                userDeptBean = findVacCountDeptUserById(taskAssigner);
            }
            //如果是前置任务指派人 并且与人员参照人员相等
            if (type.equals(SpecialUserParserEnum.PREV_ASSIGN_USER.toString())) {
                if (type.equals(SpecialUserParserEnum.PREV_ASSIGN_USER.toString()) && frontTaskAssigner.equals(userId)) {
                    return true;
                }
            }
            //如果是前置任务指派人 直属领导
            if (type.equals(SpecialUserParserEnum.PREV_ASSIGN_USER_DIRECT_LEADER.toString())) {
                userDeptBean = findVacCountDeptUserById(frontTaskAssigner);
            }
            //如果是流程启动人 并且与人员参照人员相等
            if (type.equals(SpecialUserParserEnum.STARTER_USER.toString())) {
                if (type.equals(SpecialUserParserEnum.STARTER_USER.toString()) && starterUser.equals(userId)) {
                    return true;
                }
            }

            Boolean checkUser = SpecialUserParserFactory.getParserByCode(type).checkUser(userDeptBean, userId);
            if (checkUser) {
                return true;
            }
        }
        return false;
    }

}
